#include <S3C2440addr.h>
#include <KeyDrv.h>
#include <timer.h>
#include <commlib.h>
#include <Console.h>
#include <svc.h>
#include <LedDrv.h>
#include <music.h>

void int_service() {
    unsigned char w = rINTOFFSET;
    unsigned char subw = rSUBSRCPND;

    switch (w) {
    case 1://EINT1:key1    
        on_recv_key_donw_interrupt(1);
        break;
    case 4://EINT4-7:key2
        on_recv_key_donw_interrupt(2);
        rEINTPEND = (1 << 4);// write EINTPEND.bit4 by 1 to clear interupt.
        break;
    case 2://EINT2:key3
        on_recv_key_donw_interrupt(3);
        break;
    case 0://EINT0:key4
        on_recv_key_donw_interrupt(4);
        break;
    case 12:    //INT_TIMER2
        on_timer_loop();
        break;
    case 28://0x1C
        if (subw & 0x1) { //INT_RXD0
            uart_on_recv_intr(rURXH0);
            rSUBSRCPND = (1 << 0);
        }
        //以下可能是垃圾代码,待确认删除
        else if (subw & 0x2) { //INT_TXD0
            rSUBSRCPND = (1 << 1);
        }
        //以上可能是垃圾代码
        break;
    default:
        ;
    }

    rSRCPND = (1 << w);
    rINTPND = (1 << w);
}

static void block_beep(int ms, int freq) {
    Buzzer_Freq_Set(freq);
    delay_ms(ms);
    Buzzer_Stop();
}

static void dump_regs(int* sp_top) {
    int i = 0;
    int* pR0 = sp_top - 13;
    printfk("pc = 0x%X\r\n", *sp_top);
    for(; i < 13; ++i) {
        printfk("r%d = 0x%X\r\n", i, pR0[i]);
    }
}

void on_undef_instruction() {
    unsigned int i = 0;
    block_beep(100, YINJIE_DOLPHIN_1);
    printfk("!!!!! undefine instruction !!!!!\r\n");
    dump_regs((int*)(0x32F00000 - 4)); //full stack
    while(1) {
        delay_ms(500);
        if(i % 2) set_led(LED_ALL, LED_ON);
        else set_led(LED_ALL, LED_OFF);
        ++i;
    }
}

void on_abort_prefetch() {
    printfk("!!!!!on_abort_prefetch!!!!! dead here\r\n");
    while(1);
}

void on_abort_data() {
    unsigned int i = 0;
    
    set_led(LED_ALL, LED_OFF);
    printfk("!!!!! abort data !!!!! \r\n");
    block_beep(200, YINJIE_TREBLE_3);
    
    dump_regs((int*)(0x32F00000 - 4)); //full stack
    
    while(1) {
        delay_ms(100);
        if(i % 3) {
            set_led(LED_1, LED_ON);
            set_led(LED_4, LED_ON);
            ++i;
            continue;
        }
        set_led(LED_1, LED_OFF);
        set_led(LED_4, LED_OFF);
        ++i;
    }
    while(1);
}

void on_frq() {
    printfk("!!!!!on_frq!!!!! dead here\r\n");
    while(1);
}



